package com.finance.rule.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.finance.base.constant.BaseConstants;
import com.finance.base.enums.RegionTypeEnum;
import com.finance.base.enums.StateEnum;
import com.finance.base.exception.BaseException;
import com.finance.framework.controller.BaseController;
import com.finance.framework.controller.Result;
import com.finance.framework.file.FileUtils;
import com.finance.framework.lang.Page;
import com.finance.framework.lang.PageResultBO;
import com.finance.rule.bean.pojo.SettlementRegion;
import com.finance.rule.bean.pojo.SettlementRegionDetail;
import com.finance.rule.bean.pojo.SettlementRegionList;
import com.finance.rule.export.SettlementRegionParse;
import com.finance.rule.export.SettlementRegionParseBean;
import com.finance.rule.request.SettlementRegionImportReq;
import com.finance.rule.request.SettlementRegionListReq;
import com.finance.rule.request.SettlementRegionReq;
import com.finance.rule.service.ISettlementRegionService;
import com.finance.system.bean.pojo.Region;
import com.finance.system.bean.pojo.User;
import com.finance.system.service.IRegionCodeService;
import com.finance.util.export.ExportBuilder;
import com.finance.util.export.ExportFactory;
import com.finance.util.export.ImportUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 结算区域管理
 */
@Controller
@RequestMapping("/rule/settlementregion")
public class SettlementRegionController extends BaseController{

    @Resource
    private ISettlementRegionService settlementRegionService;

    @Resource
    private IRegionCodeService regionCodeService;

    @RequestMapping("/index.htm")
    public String index(){
        return "rule/settlementregion/index";
    }

    @RequestMapping("/list")
    public Result list(SettlementRegionListReq form){
        Page page = Page.getInstance(form);
        SettlementRegionList param = new SettlementRegionList();
        param.setLevel(form.getLevel());
        param.setName(form.getName());
        Region fromRegion = convertFromRegion(form);
        Region toRegion = convertToRegion(form);
        if(fromRegion!=null){
            param.setFromCode(fromRegion.getCode());
        }
        if(toRegion!=null){
            param.setToCode(toRegion.getCode());
        }
        page.setParams(param);
        PageResultBO<SettlementRegionDetail> resultBO = settlementRegionService.listDetailByPage(page);
        return getSuccessResult(resultBO);
    }
    @RequestMapping("/lists")
    public Result settlementList(SettlementRegionListReq form){
        Page page = Page.getInstance(form);
        SettlementRegionList param = new SettlementRegionList();
        param.setLevel(form.getLevel());
        param.setName(form.getName());
        Region toRegion = convertToRegion(form);
        if(toRegion!=null){
            param.setToCode(toRegion.getCode());
        }
        page.setParams(param);
        PageResultBO<Map<String,Object>> resultBO = settlementRegionService.listDetailMapByPage(page);
        return getSuccessResult(resultBO);
    }

    @RequestMapping(value = "/updateSettlement",method = RequestMethod.POST)
    public Result updateSettlement(String id,String settlementLevel) throws IOException {
        if(StringUtils.isBlank(settlementLevel)){
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        User user = getAuthUser();
        if(user == null){
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        ObjectMapper mapper = new ObjectMapper();
        List< Map<String,String>> settlementLevelMap =mapper.readValue(settlementLevel,new TypeReference<List<Map<String,String>>>() {});
        settlementRegionService.updateSettlement(settlementLevelMap);
        return getSuccessResult(true);
    }

    private Region convertFromRegion(SettlementRegionListReq form){
        if(StringUtils.isNotBlank(form.getFromCity())){
            String city=form.getFromCity();

            Region region = new Region();
            region.setCode(city.substring(0,4));
            region.setPcode(form.getFromProvince());
            region.setProvince(form.getFromProvince());
            region.setCity(city);
            region.setLevel(Region.LEVE_CITY);
            return region;
        }
        if(StringUtils.isNotBlank(form.getFromProvince())){
            String province=form.getFromProvince();
            Region region = new Region();
            region.setCode(province.substring(0,2));
            region.setProvince(province);
            region.setLevel(Region.LEVE_PROVINCE);
            return region;
        }
        return null;
    }
    private Region convertToRegion(SettlementRegionListReq form){
        if(StringUtils.isNotBlank(form.getToCounty())){
            Region region = new Region();
            region.setCode(form.getToCounty());
            region.setPcode(form.getToCity());
            region.setProvince(form.getToProvince());
            region.setCity(form.getToCity());
            region.setLevel(Region.LEVE_COUNTY);
            return region;
        }
        if(StringUtils.isNotBlank(form.getToCity())){
            String city=form.getToCity();

            Region region = new Region();
            region.setCode(city.substring(0,4));
            region.setPcode(form.getToProvince());
            region.setProvince(form.getToProvince());
            region.setLevel(Region.LEVE_CITY);
            return region;
        }
        if(StringUtils.isNotBlank(form.getToProvince())){
            String province=form.getToProvince();

            Region region = new Region();
            region.setCode(province.substring(0,2));
            region.setLevel(Region.LEVE_PROVINCE);
            return region;
        }
        return null;
    }

    @RequestMapping(value = "/listall")
    public Result listAll(){
        List<SettlementRegion> resultBO = settlementRegionService.listAll();
        return getSuccessResult(resultBO);
    }

    @RequestMapping(value = "/add",method = RequestMethod.POST)
    public Result add(@Valid SettlementRegionReq form) throws BaseException {
        User user = getAuthUser();
        if(user == null){
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        SettlementRegion settlementRegion = new SettlementRegion();
        try {
            BeanUtils.copyProperties(settlementRegion,form);
            Region fromCity = this.convertFromCity(form);
            Region toRegion = this.convertToRegion(form);
            settlementRegion.setFromRegion(fromCity);
            settlementRegion.setToRegion(toRegion);
        } catch (Exception e) {
            throw new BaseException(BaseConstants.ERR_COPYBEAN);
        }
        settlementRegion.setCreateUid(user.getId());
        settlementRegion.setState(StateEnum.Valid.getState());

        String fromCode=form.getFromCode();
        String toCode=form.getToProvince();
        if(StringUtils.isNotEmpty(form.getToCity())){
            toCode=form.getToCity();
        }
        if(StringUtils.isNotEmpty(form.getToCounty())){
            toCode=form.getToCounty();
        }
        Region fromRegion=new Region();
        fromRegion.setCode(fromCode);
        settlementRegion.setFromRegion(fromRegion);
        Region toRegion=new Region();
        toRegion.setCode(toCode);
        settlementRegion.setToRegion(toRegion);
        settlementRegionService.add(settlementRegion);
        return getSuccessResult(true);
    }

    @RequestMapping(value = "/add.htm",method = RequestMethod.GET)
    public String add(){
        return "rule/settlementregion/add";
    }

    @RequestMapping(value = "/update.htm",method = RequestMethod.GET)
    public String update(String id, HttpServletRequest request){
        SettlementRegionDetail settlementRegion = settlementRegionService.getDetailById(Long.parseLong(id));
        request.setAttribute("settlementRegion",settlementRegion);
        return "rule/settlementregion/update";
    }

    @RequestMapping(value = "/update",method = RequestMethod.POST)
    public Result update(String id,@Valid SettlementRegionReq form){
        if(StringUtils.isEmpty(id)){
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        User user = getAuthUser();
        if(user == null){
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        SettlementRegion settlementRegion = new SettlementRegion();
        settlementRegion.setId(Long.parseLong(id));
        try {
            BeanUtils.copyProperties(settlementRegion,form);
            Region fromCity = this.convertFromCity(form);
            Region toRegion = this.convertToRegion(form);
            settlementRegion.setFromRegion(fromCity);
            settlementRegion.setToRegion(toRegion);
        } catch (Exception e) {
            throw new BaseException(BaseConstants.ERR_COPYBEAN);
        }
        settlementRegion.setUpdateUid(user.getId());

        String fromCode=form.getFromCode();
        String toCode=form.getToProvince();
        if(StringUtils.isNotEmpty(form.getToCity())){
            toCode=form.getToCity();
        }
        if(StringUtils.isNotEmpty(form.getToCounty())){
            toCode=form.getToCounty();
        }
        Region fromRegion=new Region();
        fromRegion.setCode(fromCode);
        settlementRegion.setFromRegion(fromRegion);
        Region toRegion=new Region();
        toRegion.setCode(toCode);
        settlementRegion.setToRegion(toRegion);

        settlementRegionService.update(settlementRegion);
        return getSuccessResult(true);
    }
    private Region convertFromCity(SettlementRegionReq form){
        if(StringUtils.isNotBlank(form.getFromCode())){
            Region region = new Region();
            region.setCode(form.getFromCode());
            region.setLevel(2);
            return region;
        }
        return null;
    }
    private Region convertFromCity(SettlementRegionImportReq form){
        if(StringUtils.isNotBlank(form.getFromCode())){
            Region region = new Region();
            region.setLevel(2);
            region.setCode(form.getFromCode());
            return region;
        }
        return null;
    }
    private Region convertToRegion(SettlementRegionReq form){
        if(StringUtils.isNotBlank(form.getToCounty())){
            Region region = new Region();
            region.setCode(form.getToCounty());
            region.setCity(form.getToCity());
            region.setProvince(form.getToProvince());
            region.setLevel(3);
            region.setPcode(form.getToCity());
            return region;
        }else if(StringUtils.isNotBlank(form.getToCity())){
            Region region = new Region();
            region.setCode(form.getToCity());
            region.setProvince(form.getToProvince());
            region.setLevel(2);
            region.setPcode(form.getToProvince());
            return region;
        }else if(StringUtils.isNotBlank(form.getToProvince())){
            Region region = new Region();
            region.setCode(form.getToProvince());
            region.setLevel(1);
            return region;
        }
        return null;
    }
    private Region convertToRegion(SettlementRegionImportReq form){
        if(StringUtils.isNotBlank(form.getToCounty())){
            Region region = new Region();
            region.setCode(form.getToCounty());
            region.setCity(form.getToCity());
            region.setProvince(form.getToProvince());
            region.setPcode(form.getToCity());
            region.setLevel(3);
            return region;
        }else if(StringUtils.isNotBlank(form.getToCity())){
            Region region = new Region();
            region.setCode(form.getToCity());
            region.setProvince(form.getToProvince());
            region.setPcode(form.getToProvince());
            region.setLevel(2);
            return region;
        }else if(StringUtils.isNotBlank(form.getToProvince())){
            Region region = new Region();
            region.setLevel(1);
            region.setCode(form.getToProvince());
            return region;
        }
        return null;
    }
    @RequestMapping("/delete")
    public Result delete(String ids){
        if (StringUtils.isEmpty(ids)){
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        User user = getAuthUser();
        if(user == null){
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        List<String> list = Arrays.asList(ids.split(","));
        if(list.size()>0){
            boolean ret = settlementRegionService.delete(user.getId().toString(),list);
            return getSuccessResult(ret);
        }
        return getSuccessResult(true);
    }

    /**
     * 导入Excel模板下载
     */
    @RequestMapping("/exporttemplate")
    public void export(HttpServletResponse response) {
        try {
            ExportBuilder builder = new ExportBuilder
                    (SettlementRegionParseBean.class,
                            new SettlementRegionParse()
                    );
            ExportFactory factory = ExportFactory.getExportFactory(
                    builder);
            factory.setDataList(new ArrayList<SettlementRegion>()).outPut(response);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);

        }
    }


    /**
     * 导入结果下载
     */
    @RequestMapping("/down")
    public void importData(String fileKey, HttpServletResponse response) {
        FileUtils.downFile(fileKey, response);
    }

    /**
     * 导入
     */
    @RequestMapping("/import")
    public Result importData(@RequestParam("file") CommonsMultipartFile[] multipartFile) {
        User user = getAuthUser();
        if(user == null){
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        InputStream in = null;
        List<SettlementRegion> errList = null;
        List<String> errMsg = null;
        int successNums = 0;
        int totalNums = 0;
        try {
            in = multipartFile[0].getInputStream();
            List<SettlementRegionParseBean> list = ImportUtil.getImportFactory(in).outResult(SettlementRegionParseBean.class);
            errList = new ArrayList<SettlementRegion>();
            errMsg = new ArrayList<String>();
            if (list != null && list.size() > 0) {
                for (SettlementRegionParseBean bean : list) {
                    SettlementRegionImportReq form = new SettlementRegionImportReq();
                    if(StringUtils.isNotBlank(bean.getLevelImport())){
                        String level = bean.getLevelImport().trim();
                        if("一类区域".equals(level)){
                            form.setLevel(String.valueOf(RegionTypeEnum.LEVEL_I.getLevel()));
                        }else if("二类区域".equals(level)){
                            form.setLevel(String.valueOf(RegionTypeEnum.LEVEL_II.getLevel()));
                        }else if("三类区域".equals(level)){
                            form.setLevel(String.valueOf(RegionTypeEnum.LEVEL_III.getLevel()));
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getFromProvinceImport())){
                        String fromProvinceCode = regionCodeService.getCodeByName(bean.getFromProvinceImport().trim());
                        if(StringUtils.isNotBlank(fromProvinceCode)){
                            form.setFromProvinceCode(fromProvinceCode);
                            form.setFromCode(fromProvinceCode);
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getFromProvinceImport())&&StringUtils.isNotBlank(bean.getFromCityImport())){
                        String fromProvinceCode = regionCodeService.getCodeByName(bean.getFromProvinceImport().trim());
                        String fromCityCode = regionCodeService.getCodeByNameAndParent(bean.getFromCityImport().trim(),fromProvinceCode);
                        if(StringUtils.isNotBlank(fromCityCode)){
                            form.setFromCityCode(fromCityCode);
                            form.setFromCode(fromCityCode);
                            form.setFromCityError("true");
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getToProvinceImport())){
                        String toProvince = regionCodeService.getCodeByName(bean.getToProvinceImport().trim());
                        if(StringUtils.isNotBlank(toProvince)){
                            form.setToProvince(toProvince);
                            form.setToCode(toProvince);
                        }
                    }

                    if(StringUtils.isNotBlank(bean.getToProvinceImport())&&StringUtils.isNotBlank(bean.getToCityImport())){
                        String toProvince = regionCodeService.getCodeByName(bean.getToProvinceImport().trim());
                        String toCity = regionCodeService.getCodeByNameAndParent(bean.getToCityImport().trim(),toProvince);
                        if(StringUtils.isNotBlank(toCity)){
                            form.setToCity(toCity);
                            form.setToCode(toCity);
                            form.setToCityError("true");
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getToProvinceImport())&&StringUtils.isNotBlank(bean.getToCityImport())&&StringUtils.isNotBlank(bean.getToCountyImport())){
                        String toProvince = regionCodeService.getCodeByName(bean.getToProvinceImport().trim());
                        String toCity = regionCodeService.getCodeByNameAndParent(bean.getToCityImport().trim(),toProvince);
                        String toCounty = regionCodeService.getCodeByNameAndParent(bean.getToCountyImport().trim(),toCity);
                        if(StringUtils.isNotBlank(toCounty)){
                            form.setToCounty(toCounty);
                            form.setToCode(toCounty);
                            form.setToCountyError("true");
                        }
                    }
                    form.setFromProvinceImport(bean.getFromProvinceImport());
                    form.setFromCityImport(bean.getFromCityImport());
                    List<String> msgList = validate(form);
                    try {
                        BeanUtils.copyProperties(form, bean);
                    }catch (Exception e){
                        throw  new BaseException(BaseConstants.ERR_COPYBEAN);
                    }
                    SettlementRegion settlementRegion  = new SettlementRegion();
                    try {
                        BeanUtils.copyProperties(settlementRegion,form);
                        Region fromCity = this.convertFromCity(form);
                        Region toRegion = this.convertToRegion(form);
                        settlementRegion.setFromRegion(fromCity);
                        settlementRegion.setToRegion(toRegion);
                    } catch (Exception e) {
                        throw new BaseException(BaseConstants.ERR_COPYBEAN);
                    }
                    settlementRegion.setCreateUid(user.getId());
                    settlementRegion.setState(StateEnum.Valid.getState());

                    String fromCode=form.getFromCode();
                    String toCode=form.getToProvince();
                    if(StringUtils.isNotEmpty(form.getToCity())){
                        toCode=form.getToCity();
                    }
                    if(StringUtils.isNotEmpty(form.getToCounty())){
                        toCode=form.getToCounty();
                    }
                    Region fromRegion=new Region();
                    fromRegion.setCode(fromCode);
                    settlementRegion.setFromRegion(fromRegion);
                    Region toRegion=new Region();
                    toRegion.setCode(toCode);
                    settlementRegion.setToRegion(toRegion);
                    settlementRegion.setState(StateEnum.Valid.getState());
                    settlementRegion.setCreateUid(user.getId());
                    if (msgList == null || msgList.size() == 0) {
                        try {
                            settlementRegionService.add(settlementRegion);
                        } catch (BaseException e) {
                            errMsg.add(e.getErrorMsg());
                            errList.add(settlementRegion);
                        } catch (Exception e) {
                            errMsg.add(e.getMessage());
                            errList.add(settlementRegion);

                        }
                    }else{

                        StringBuffer msgStr = new StringBuffer();
                        for (String msg : msgList) {
                            msgStr.append(msg + "||");
                        }
                        msgStr.replace(msgStr.lastIndexOf("||"), msgStr.length(), "");
                        errMsg.add(msgStr.toString());
                        errList.add(settlementRegion);

                    }
                }
                successNums = list.size() - errList.size();
                totalNums = list.size();

            }
        } catch (Exception e)

        {
            return getFailResult(BaseConstants.ERR_UNKOWN, e.getMessage());
        } finally

        {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }

        String fileKey = null;
        if (errList != null && errList.size() > 0)

        {
            String path = getRealPath("");
            File file = null;
            try {
                path += System.currentTimeMillis() + BaseConstants.DEFAULT_EXPORT_FILE_SUFFIX;
                file = new File(path);
                ExportBuilder builder = new ExportBuilder
                        (SettlementRegionParseBean.class,
                                new SettlementRegionParse()
                        );
                ExportFactory factory = ExportFactory.getExportFactory(
                        builder);
                factory.setErrMsgList(errMsg).setDataList(errList).outPut(file);
                fileKey = FileUtils.uploadFile("import/settlementregion/", file.getName(), file);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            } finally {
                if (file != null) {
                    file.delete();
                }
            }
        }

        Map<String, String> returnMap = new HashMap<String, String>();
        returnMap.put("fileKey", fileKey);
        returnMap.put("successNums", String.valueOf(successNums));
        returnMap.put("totalNums", String.valueOf(totalNums));
        return getSuccessResult(returnMap);
    }


}
